
#include <BMap>
#include <BFont>
#include <BFile>
#include <BStyle>
#include <BPainter>

#include <BShortcut>
#include <BLabel>
#include <BButton>
#include <BCheckBox>
#include <BLineEdit>
#include <BTextEdit>
#include <BMessageBox>
#include <BFileDialog>
#include <BColorDialog>

#include <BSlider>
#include <BLongSlider>
#include <BRealSlider>
#include <BFloatSlider>
#include <BDoubleSlider>

#include <BXmlDocument>
#include <BSonDocument>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BStackLayout>

#include <BCursor>
#include <BSystem>
#include <BReadWrite>
#include <BApplication>

#include "MainWindow.h"

MainWindow::MainWindow()
{
	BWidget* leftWidget = new BWidget("left");
	leftWidget->setWidthPolicy(Policy_Growing);
	{
		BGridLayout* gridLayout = new BGridLayout();
		gridLayout->setSplitable(true);
		gridLayout->setRowSpacing(6);
		gridLayout->setColumnSpacing(6);
		gridLayout->setMargin(3);
		{
			BLabel* dialogLabel = new BLabel(Form_IconTextOverlap, u8"对话框");
			dialogLabel->setImage(new BImage("data/image/background-green-light.png"));
			dialogLabel->setImageSize(-1);

			BButton* fileButton = new BButton("File Button");
			fileButton->setIcon(new BIcon("data/icon/fileopen.png"));
			fileButton->setIconSize(32, 32);
			fileButton->setForm(Form_TextUnderIcon);
			fileButton->setAlign(Align_BottomCenter);
			fileButton->setTips("Open file dialog to choose image for button and tree widget background.");

			BButton* messageButton = new BButton("Message\nButton");
			messageButton->setTips("Open message dialog.");

			BButton* colorButton = new BButton("ColorButton");
			colorButton->setBorder(5);
			colorButton->setMargin(5);
			colorButton->setGraph(Graph_Circle_Fill);
			colorButton->setTips("Open color dialog to set button color.");

			BComboBox* colorComboBox = createColorBox();
			colorComboBox->setValue(colorButton->color());
			colorComboBox->setText(u8"黑色");
			colorComboBox->setEditable(true);

			BLabel* spinBoxLabel = new BLabel("Spinbox");
			_spinBox = new BSpinBox(-10000, 10000);
			_spinBox->setName("spinbox");
			_spinBox->setValue(1234);
			_spinBox->setAlign(Align_Center);
			_spinBox->setFormulable(true);
			_spinBox->setArrowVisible(true);
			_spinBox->setPrefix("Int");
			_spinBox->setSuffix("suffix");

			_realSpinBox = new BRealSpinBox(-10000, 10000);
			_realSpinBox->setName("real-spinbox");
			_realSpinBox->setValue(1234);
			_realSpinBox->setAlign(Align_Center);
			_realSpinBox->setFormulable(true);
			_realSpinBox->setArrowVisible(true);
			_realSpinBox->setPrefix("Real");
			_realSpinBox->setSuffix("suffix");

			BLabel* floatSpinBoxLabel = new BLabel("Float\nSpinbox");
			floatSpinBoxLabel->setAlign(Align_TopCenter);
			_floatSpinBox = new BFloatSpinBox(-10000, 10000);
			_floatSpinBox->setName("float-spinbox");
			_floatSpinBox->setDecimals(6);
			_floatSpinBox->setValue(5678.123f);
			_floatSpinBox->setAlign(Align_Center);
			_floatSpinBox->setFormulable(true);
			_floatSpinBox->setArrowVisible(true);
			_floatSpinBox->setPrefix("Float");
			_floatSpinBox->setSuffix("suffix");

			_scrollBar = new BScrollBar(_floatSpinBox->range());
			_scrollBar->setPage((int)_floatSpinBox->range().size() / 10);

			BHBoxLayout* doubleLayout = new BHBoxLayout("double");
			{
				_doubleSpinBox = new BDoubleSpinBox(-10000, 10000);
				_doubleSpinBox->setName("double-spinbox");
				_doubleSpinBox->setDecimals(6);
				_doubleSpinBox->setValue(5678.123);
				_doubleSpinBox->setAlign(Align_Center);
				_doubleSpinBox->setArrowVisible(false);
				_doubleSpinBox->setFormulable(true);
				_doubleSpinBox->setPrefix("Double");
				_doubleSpinBox->setSuffix("suffix");

				doubleLayout->addWidget(_doubleSpinBox);
				doubleLayout->addWidget(createHtml("<c>mm/s<sup>2"));
			}

			_doubleSlider = new BDoubleSlider(_doubleSpinBox->range());

			BLabel* synchroLabel = new BLabel("Synchro");
			BCheckBox* timeSynchroBox = new BCheckBox("Sync Time");
			BCheckBox* dateSynchroBox = new BCheckBox("Sync Date");

			BLabel* timeLabel = new BLabel("Time-Date");

			_timeEdit = new BTimeEdit();
			_timeEdit->setAlign(Align_LeftCenter);
			_timeEdit->setTime(BSystem::LocalTime());
			_timeEdit->setFormat(u8"hh123时 456mm分 ss321秒");
			_timeEdit->setStyleSheet("font-mono:true");

			_dateEdit = new BDateEdit();
			_dateEdit->setAlign(Align_LeftCenter);
			_dateEdit->setDate(BSystem::LocalDate());
			_dateEdit->setFormat(u8"请编辑Y年年有余M月D日");

			gridLayout->addWidget(0, 0, dialogLabel);
			gridLayout->addWidget(0, 1, fileButton);
			gridLayout->addWidget(0, 2, messageButton);
			gridLayout->addWidget(1, 0, new BLabel("choose color"));
			gridLayout->addWidget(1, 1, colorButton);
			gridLayout->addWidget(1, 2, colorComboBox);
			gridLayout->addWidget(2, 0, spinBoxLabel);
			gridLayout->addWidget(2, 1, _spinBox);
			gridLayout->addWidget(2, 2, _realSpinBox);
			gridLayout->addWidget(3, 0, floatSpinBoxLabel);
			gridLayout->addWidget(3, 1, _floatSpinBox);
			gridLayout->addLayout(3, 2, doubleLayout);
			gridLayout->addWidget(4, 1, _scrollBar);
			gridLayout->addWidget(4, 2, _doubleSlider);
			gridLayout->addWidget(5, 0, synchroLabel);
			gridLayout->addWidget(5, 1, timeSynchroBox);
			gridLayout->addWidget(5, 2, dateSynchroBox);
			gridLayout->addWidget(6, 0, timeLabel);
			gridLayout->addWidget(6, 1, _timeEdit);
			gridLayout->addWidget(6, 2, _dateEdit);
			gridLayout->setColumnStretch(1, 5);

			connect(_spinBox, Signal_EditFinished, &MainWindow::slotSpinBoxEditFinished);
			connect(_realSpinBox, Signal_EditFinished, &MainWindow::slotRealSpinBoxEditFinished);
			connect(_floatSpinBox, Signal_EditFinished, &MainWindow::slotFloatSpinBoxEditFinished);
			connect(_scrollBar, Signal_Scrolling, &MainWindow::slotScrollBarScrolling);
			connect(_doubleSpinBox, Signal_EditFinished, &MainWindow::slotDoubleSpinBoxEditFinished);
			connect(_doubleSlider, Signal_Sliding, &MainWindow::slotDoubleSliderSliding);

			connect(colorButton, Signal_Clicked, &MainWindow::slotColorButtonClicked);
			connect(fileButton, Signal_Clicked, &MainWindow::slotFileButtonClicked);
			connect(messageButton, Signal_Clicked, &MainWindow::slotMessageButtonClicked);
			connect(timeSynchroBox, Signal_Checked, &MainWindow::slotTimeSynchroChecked);
			connect(dateSynchroBox, Signal_Checked, &MainWindow::slotDateSynchroChecked);
		}

		BHBoxLayout* hlayout1 = new BHBoxLayout();
		{
			BTableWidget* tableWidget = createTableWidget();

			BListWidget* listWidget = createListWidget();

			hlayout1->addWidget(tableWidget);
			hlayout1->addWidget(listWidget);

			connect(tableWidget, Signal_ItemDoubleClicked, &MainWindow::slotTableItemDoubleClicked);
			connect(listWidget, Signal_ItemSelected, &MainWindow::slotListItemSelected);
		}

		BVBoxLayout* vlayout = new BVBoxLayout(leftWidget);
		vlayout->setSplitable(true);
		vlayout->setSpacing(16);
		vlayout->addLayout(gridLayout);
		vlayout->addLayout(hlayout1, 10);
	}

	BWidget* rightWidget = new BWidget("right");
	rightWidget->setWidthPolicy(Policy_Growing);
	{
		BHBoxLayout* hlayout0 = new BHBoxLayout();
		hlayout0->setHeightPolicy(Policy_Preferred);
		{
			BLabel* fileLabel = new BLabel("file");
			_filePathComboBox = new BComboBox();
			_filePathComboBox->addItem("../../manual/chinese/index.html");
			_filePathComboBox->addItem("./data/scene.xml");
			_filePathComboBox->addItem("./data/scene.son");
			_filePathComboBox->setCurrentIndex(0);
			_filePathComboBox->setTips("Right click to open special file.");
			_filePathComboBox->setEditable(true);

			_loadFileButton = new BButton("Load");
			_loadFileButton->setName("load");

			hlayout0->addWidget(fileLabel);
			hlayout0->addWidget(_filePathComboBox, 10);
			hlayout0->addWidget(_loadFileButton);
		}

		BWidget* stackWidget = new BWidget();
		BStackLayout* stackLayout = new BStackLayout(stackWidget);
		{
			_htmlWidget = new BHtmlWidget();
			
			_treeWidget = new BTreeWidget();
			_treeWidget->setName("tree");
			_treeWidget->setIndent(23);

			_textEdit = new BTextEdit();

			stackLayout->addWidget(_htmlWidget);
			stackLayout->addWidget(_treeWidget);
			stackLayout->addWidget(_textEdit);
		}

		BHBoxLayout* hlayout1 = new BHBoxLayout();
		hlayout1->setHeightPolicy(Policy_Preferred);
		{
			BLabel* fileNameLabel = new BLabel("fileName");
			_sheetFileNameEdit = new BLineEdit("data/style/widget.css");
			_saveSheetButton = new BButton("Save");
			_saveSheetButton->setName("save");
			_saveSheetButton->setEnabled(false);

			hlayout1->addWidget(fileNameLabel);
			hlayout1->addWidget(_sheetFileNameEdit, 10);
			hlayout1->addWidget(_saveSheetButton);
		}

		_styleSheetEdit = new BTextEdit;
		StyleFormat* styleFormat = new StyleFormat();
		styleFormat->setAsset(_styleSheetEdit);
		_styleSheetEdit->setTextFormat(styleFormat);
		_styleSheetEdit->load(_sheetFileNameEdit->text());
		BShortcut* shortcut = new BShortcut("ctrl+s", _styleSheetEdit);
		_styleSheetEdit->setAsset(shortcut);

		BVBoxLayout* vlayout = new BVBoxLayout(rightWidget);
		vlayout->setSplitable(true);
		vlayout->setSpacing(8);
		vlayout->addLayout(hlayout0, 0);
		vlayout->addWidget(stackWidget, 100);
		vlayout->addLayout(hlayout1, 0);
		vlayout->addWidget(_styleSheetEdit, 100);

	}

	BHBoxLayout* splitLayout = new BHBoxLayout(this);
	splitLayout->setSpacing(10);
	splitLayout->setSplitable(true);
	splitLayout->addWidget(leftWidget);
	splitLayout->addWidget(rightWidget);

	connect(_filePathComboBox, Signal_RightClicked, &MainWindow::slotFilePathRightClicked);
	connect(_filePathComboBox, Signal_EditFinished, &MainWindow::slotFilePathEditFinished);
	connect(_loadFileButton, Signal_Clicked, &MainWindow::slotLoadButtonClicked);
	connect(_sheetFileNameEdit, Signal_EditFinished, &MainWindow::slotSheetFileNameEdited);
	connect(_sheetFileNameEdit, Signal_DoubleClicked, &MainWindow::slotChooseSheetFile);
	connect(_styleSheetEdit, Signal_EditFinished, &MainWindow::slotStyleSheetEditFinished);
	connect(_saveSheetButton, Signal_Clicked, &MainWindow::slotSaveSheetButtonClicked);

	connect(_styleSheetEdit->asset(), Signal_Triggered, &MainWindow::slotShortcutTriggered);
}
MainWindow::~MainWindow()
{

}

BComboBox* MainWindow::createColorBox()
{
	BComboBox* colorComboBox = new BComboBox(Form_IconText);
	colorComboBox->addItem(Graph_Square_Fill, u8"黑色", BColor(0));
	colorComboBox->addItem(Graph_Square_Fill, u8"花白", BColor(255, 250, 240));
	colorComboBox->addItem(Graph_Square_Fill, u8"棕色", BColor(128, 42, 42));
	colorComboBox->addItem(Graph_Square_Fill, u8"森林绿", BColor(34, 139, 34));
	colorComboBox->addItem(Graph_Square_Fill, u8"淡灰色", BColor(220, 220, 220));
	colorComboBox->addItem(Graph_Square_Fill, u8"米色", BColor(163, 148, 128));
	colorComboBox->addItem(Graph_Square_Fill, u8"草地绿", BColor(124, 252, 0));
	colorComboBox->addItem(Graph_Square_Fill, u8"幽霖白", BColor(248, 248, 255));
	colorComboBox->addItem(Graph_Square_Fill, u8"锻浓黄土色", BColor(138, 54, 15));
	colorComboBox->addItem(Graph_Square_Fill, u8"酸橙绿", BColor(50, 205, 50));
	colorComboBox->addItem(Graph_Square_Fill, u8"蜜露橙", BColor(240, 255, 240));
	colorComboBox->addItem(Graph_Square_Fill, u8"锻棕土色", BColor(135, 51, 36));
	colorComboBox->addItem(Graph_Square_Fill, u8"象牙白", BColor(250, 255, 240));
	colorComboBox->addItem(Graph_Square_Fill, u8"巧克力色", BColor(210, 105, 30));
	colorComboBox->addItem(Graph_Square_Fill, u8"草绿色", BColor(107, 142, 35));
	colorComboBox->addItem(Graph_Square_Fill, u8"亚麻色", BColor(250, 240, 230));
	colorComboBox->addItem(Graph_Square_Fill, u8"肉色", BColor(255, 125, 64));
	colorComboBox->addItem(Graph_Square_Fill, u8"暗绿色", BColor(48, 128, 20));
	colorComboBox->addItem(Graph_Square_Fill, u8"海军白", BColor(255, 222, 173));
	colorComboBox->addItem(Graph_Square_Fill, u8"黄褐色", BColor(240, 230, 140));
	colorComboBox->addItem(Graph_Square_Fill, u8"海绿色", BColor(46, 139, 87));
	colorComboBox->addItem(Graph_Square_Fill, u8"浅米色", BColor(253, 245, 230));
	colorComboBox->addItem(Graph_Square_Fill, u8"玫瑰红", BColor(188, 143, 143));
	colorComboBox->addItem(Graph_Square_Fill, u8"嫩绿色", BColor(0, 255, 127));
	for (int i = 0; i < colorComboBox->itemCount(); i++)
	{
		BComboItem* item = colorComboBox->item(i);
		item->setColor(item->value());
	}
	return colorComboBox;
}
BTableWidget* MainWindow::createTableWidget()
{
	BTableWidget* tableWidget = new BTableWidget();
	tableWidget->setBorder(15);
	tableWidget->setMargin(15);
	tableWidget->setRowSpacing(4);
	tableWidget->setColumnSpacing(4);
	tableWidget->setRowCount(3);
	tableWidget->setColumnCount(2);
	tableWidget->setRowLabel(0, "row0");
	tableWidget->setRowLabel(1, "row1");
	tableWidget->setRowLabel(2, "row2");
	tableWidget->setColumnLabel(0, "column0");
	tableWidget->setColumnLabel(1, "column1");
	//tableWidget->setGridStyle(Grid_Crossing);
	{
		BLineEdit* itemEdit = new BLineEdit(tableWidget);
		itemEdit->setName("editer");
		itemEdit->setBorder(0);
		itemEdit->setMargin(0);
		itemEdit->setStyleSheet("margin-color:empty");
		itemEdit->hide();

		BComboBox* comboBox = new BComboBox();
		comboBox->setEditable(true);
		comboBox->addItem("123456789");
		comboBox->addItem("abcdefg");
		comboBox->addItem("third party");
		comboBox->setHeightPolicy(Policy_Preferred);

		BButton* button = new BButton(u8"BWE软件框架");

		tableWidget->setItem(0, 0, comboBox);
		tableWidget->setItem(0, 1, "This is just test text");
		tableWidget->setItem(1, 0, "margin-color:empty");
		tableWidget->setItem(1, 1, button);
		tableWidget->setItem(2, 0, "Third row one");
		tableWidget->setItem(2, 1, "Third row two");

		tableWidget->item(0, 0)->setLineFeed(true);

		connect(itemEdit, Signal_EditFinished, &MainWindow::slotItemTextEdited);
		connect(itemEdit, Signal_Focused, &MainWindow::slotItemTextEditFocused);
	}

	BHBoxLayout* policyLayout = new BHBoxLayout(tableWidget, Part_Bottom);
	{
		BMenu* policyMenu = new BMenu();
		policyMenu->addAction("Fixed")->setAsset(Policy_Fixed);
		policyMenu->addAction("Preferred")->setAsset(Policy_Preferred);
		policyMenu->addAction("Shrinking")->setAsset(Policy_Shrinking);
		policyMenu->addAction("Expanding")->setAsset(Policy_Expanding);
		for (int i = 0; i < policyMenu->count(); i++)
		{
			policyMenu->action(i)->setCheckable(true);
		}
		policyMenu->setProperty("table", tableWidget);

		BLabel* rowPolicyLabel = new BLabel("row-policy");
		rowPolicyLabel->setAlign(Align_Center);
		BButton* rowPolicyButton = new BButton(policyMenu);
		rowPolicyButton->setName("row-policy");

		BLabel* columnPolicyLabel = new BLabel("column-policy");
		columnPolicyLabel->setAlign(Align_Center);
		BButton* columnPolicyButton = new BButton(policyMenu);
		columnPolicyButton->setName("column-policy");

		policyLayout->addWidget(rowPolicyLabel);
		policyLayout->addWidget(rowPolicyButton, 10);
		policyLayout->addSpacer(10);
		policyLayout->addWidget(columnPolicyLabel);
		policyLayout->addWidget(columnPolicyButton, 10);

		connect(rowPolicyButton, Signal_Clicked, &MainWindow::slotPolicyButtonClicked);
		connect(columnPolicyButton, Signal_Clicked, &MainWindow::slotPolicyButtonClicked);
		connect(policyMenu, Signal_Triggered, &MainWindow::slotPolicyMenuTrigger);
	}

	return tableWidget;
}
BListWidget* MainWindow::createListWidget()
{
	BListWidget* listWidget = new BListWidget();
	listWidget->setName("list");
	listWidget->setTitle("widget of main window");
	listWidget->setTitleVisible(true);
	listWidget->setAreaPolicy(Policy_Growing, Policy_Preferred);

	listWidget->addItem(new BSlider());
	listWidget->addItem(new BLongSlider());
	listWidget->addItem(new BRealSlider());
	listWidget->addItem(new BFloatSlider());
	listWidget->addItem(new BDoubleSlider());

	return listWidget;
}
BTreeItem* MainWindow::createTreeItem(BXmlNode* node)
{
	if (node)
	{
		BTreeItem* item = new BTreeItem(node->name());
		item->setAsset(node);

		const BMap<BString, BString>& attribs = node->attribMap();
		for (auto it = attribs.begin(); it.valid(); ++it)
		{
			BString text;
			text << '[' << it.key() << " = " << it.value() << ']';
			BTreeItem* child = item->addChild(text);
			assignIcon(child);
		}

		if (node->text().size())
		{
			BTreeItem* child = item->addChild(node->text());
			assignIcon(child);
		}

		for (int i = 0; i < node->childCount(); i++)
		{
			BXmlNode* childNode = node->child(i);
			BTreeItem* childItem = createTreeItem(childNode);
			item->addChild(childItem);
		}
		assignIcon(item);
		return item;
	}
	return 0;
}
BTreeItem* MainWindow::createTreeItem(BSonNode* node)
{
	if (node)
	{
		BTreeItem* item = new BTreeItem(node->name());
		item->setAsset(node);

		const BMap<BString, BString>& attribs = node->attribMap();
		for (auto it = attribs.begin(); it.valid(); ++it)
		{
			BString text;
			text << '[' << it.key() << " = " << it.value() << ']';
			BTreeItem* child = item->addChild(text);
			assignIcon(child);
		}

		if (node->text().size())
		{
			BTreeItem* child = item->addChild(node->text());
			child->setAlign(Align_None);
			assignIcon(child);
		}

		for (int i = 0; i < node->childCount(); i++)
		{
			BSonNode* childNode = node->child(i);
			BTreeItem* childItem = createTreeItem(childNode);
			item->addChild(childItem);
		}
		assignIcon(item);
		return item;
	}
	return 0;
}
bool MainWindow::assignIcon(BTreeItem* item)
{
	const BStyle* style = this->realStyle();
	if (item->asset().valid())
	{
		item->setIcon(style->icon("node"));
		return true;
	}
	if (item->text().beginWith('[') && item->text().endWith(']'))
		item->setIcon(style->icon("attrib"));
	else
		item->setIcon(style->icon("text"));
	return true;
}
BHtmlWidget* MainWindow::createHtml(const BString& text)
{
	BXmlDocument document;
	if (BXmlNode* node = document.read(text))
	{
		BHtmlItem* body = new BHtmlItem(node);
		BHtmlWidget* htmlWidget = new BHtmlWidget();
		htmlWidget->setBody(body);
		htmlWidget->setSizePolicy(Policy_Preferred);
		htmlWidget->setScrollHint(ScrollHint_None);
		htmlWidget->setBorder(0);
		return htmlWidget;
	}
	return 0;
}

void MainWindow::slotColorButtonClicked(BObject* object)
{
	BButton* button = (BButton*)object;
	BColor color = BColorDialog::ChooseColor(0, "Choose Button Color", button->color());
	button->setColor(color);
}
void MainWindow::slotSpinBoxEditFinished(BObject* object, const BValue& value)
{
	BReal v = value;
	BRealSpinBox* spinbox = (BRealSpinBox*)this->find("real-spinbox");
	spinbox->setValue(v);
}
void MainWindow::slotRealSpinBoxEditFinished(BObject* object, const BValue& value)
{
	BReal v = value;
	BSpinBox* spinbox = (BSpinBox*)this->find("spinbox");
	spinbox->setValue((int)v);
}
void MainWindow::slotFloatSpinBoxEditFinished(BObject* object, const BValue& value)
{
	float v = value;
	BDoubleSpinBox* spinbox = (BDoubleSpinBox*)this->find("double-spinbox");
	spinbox->setValue(v);
}
void MainWindow::slotScrollBarScrolling(BObject* object, const BValue& value)
{
	int begin = value;
	_floatSpinBox->setValue((float)begin + _scrollBar->page() / 2);
}
void MainWindow::slotDoubleSpinBoxEditFinished(BObject* object, const BValue& value)
{
	double v = value;
	BFloatSpinBox* spinbox = (BFloatSpinBox*)this->find("float-spinbox");
	spinbox->setValue((float)v);
}
void MainWindow::slotDoubleSliderSliding(BObject* object, const BValue& value)
{
	double dval = value;
	_doubleSpinBox->setValue(dval);
}
void MainWindow::slotFileButtonClicked(BObject* object)
{
	BButton* button = (BButton*)object;
	static BFileDialog* fileDialog = new BFileDialog(this);
	fileDialog->setEditable(true);
	//fileDialog->setFolderFirst(false);
	const BString& fileName = fileDialog->openFile("Open Image file", "./data");
	if (fileName.size())
	{
		BImage* image = ReadFile<BImage>(fileName);
		BIcon* icon = new BIcon(image);
		button->setIcon(icon);
		BWidget* treeWidget = this->find("tree");
		BStyle* style = treeWidget->style();
		if (!style)
		{
			style = new BStyle();
			treeWidget->setStyle(style);
		}
		style->setImage(Image_Background, image);
	}
}
void MainWindow::slotMessageButtonClicked()
{
	BMessageBox::Question(this, "Question", "Do you like this sample code ?", Button_Yes | Button_No);
}
void MainWindow::slotTimeSynchroChecked(BObject* object, const BValue& value)
{
	bool checked = value;
	_timeEdit->setSynchro(checked);
}
void MainWindow::slotDateSynchroChecked(BObject* object, const BValue& value)
{
	bool checked = value;
	_dateEdit->setSynchro(checked);
}
void MainWindow::slotFilePathRightClicked()
{
	const BString& fileName = BFileDialog::OpenFile(this, "Browser file");
	if (fileName.empty())
		return;
	if (!_filePathComboBox->setText(fileName))
	{
		_filePathComboBox->addItem(fileName);
		_filePathComboBox->setText(fileName);
	}
}
void MainWindow::slotFilePathEditFinished(BObject* object, const BValue& value)
{
	const BString& text = value;
	if (BComboItem* item = _filePathComboBox->current())
	{
		item->setText(text);
	}
}
void MainWindow::slotLoadButtonClicked()
{
	const BString& fileName = _filePathComboBox->text();
	if (!BFile::Exist(fileName))
		return;

	if (fileName.endWith(".html"))
	{
		_htmlWidget->load(fileName);
		_htmlWidget->show();
		return;
	}
	if (fileName.endWith(".xml"))
	{
		_treeWidget->clearItems();
		BXmlDocument document;
		BXmlNode* xmlRoot = document.load(fileName);
		if (!xmlRoot)
		{
			BMessageBox::Critical("Load xml", "Load xml file failed !", Button_Close);
			return;
		}
		BTreeItem* rootItem = createTreeItem(xmlRoot);
		_treeWidget->addItem(rootItem);
		_treeWidget->show();
		return;
	}
	if (fileName.endWith(".son") || fileName.endWith(".osc"))
	{
		_treeWidget->clearItems();
		BSonDocument document;
		if (BSonNode* sonode = document.load(fileName))
		{
			BTreeItem* rootItem = createTreeItem(sonode);
			_treeWidget->addItem(rootItem);
		}
		_treeWidget->show();
		return;
	}
}

void MainWindow::slotTableItemDoubleClicked(BTableWidget* tableWidget, const BValue& value)
{
	BTableItem* item = value;
	if (!item)
	{
		BPoint pos = BCursor::GetPos() - tableWidget->globalPos();
		int row = tableWidget->rowAt(pos.y());
		int column = tableWidget->columnAt(pos.x());
		item = new BTableItem();
		tableWidget->setItem(row, column, item);
	}
	BLineEdit* itemEdit = (BLineEdit*)tableWidget->find("editer");
	itemEdit->setAsset(item);
	itemEdit->setAlign(item->align());
	itemEdit->setRect(item->textArea());
	itemEdit->setText(item->text());
	itemEdit->popup();
}
void MainWindow::slotListItemSelected(BListWidget* listWidget, const BValue& value)
{
	if (BListItem* item = value)
	{
		if (BWidget* widget = item->asset())
		{
			widget->fresh();
		}
	}
	else
	{
		int a = 0;
	}
}
void MainWindow::slotItemTextEdited(BObject* object, const BValue& value)
{
	BLineEdit* edit = (BLineEdit*)object;
	BTableItem* item = object->asset();
	item->setText(value);
	edit->hide();
}
void MainWindow::slotItemTextEditFocused(BObject* object, const BValue& value)
{
	if (value == false)
	{
		BLineEdit* edit = (BLineEdit*)object;
		edit->hide();
	}
}
void MainWindow::slotPolicyButtonClicked(BObject* object, const BValue& value)
{
	BButton* button = dynamic_cast<BButton*>(object);
	BMenu* menu = button->menu();
	menu->setAsset(button);
	int policies = button->asset();
	for (int i = 0; i < menu->count(); i++)
	{
		BAction* action = menu->action(i);
		PolicyFlag policy = action->asset();
		action->setChecked(policies & policy);
	}
}
void MainWindow::slotPolicyMenuTrigger(BObject* object, const BValue& value)
{
	BMenu* menu = dynamic_cast<BMenu*>(object);
	BString text;
	int policies = 0;
	for (int i = 0; i < menu->count(); i++)
	{
		BAction* action = menu->action(i);
		if (action->checked())
		{
			PolicyFlag policy = action->asset();
			policies |= policy;
			text << action->text() << ',';
		}
	}
	text -= ',';
	BButton* button = menu->asset();
	button->setText(text);
	button->setAsset(policies);
	BTableWidget* tableWidget = object->property("table");
	if (button->name() == "row-policy")
	{
		tableWidget->setRowPolicy(policies);
	}
	if (button->name() == "column-policy")
	{
		tableWidget->setColumnPolicy(policies);
	}
}

void MainWindow::slotSheetFileNameEdited()
{
	const BString& fileName = _sheetFileNameEdit->text();
	if (fileName.size() && fileName != _styleSheetEdit->name())
		_saveSheetButton->setEnabled(true);
	else
		_saveSheetButton->setEnabled(false);
}
void MainWindow::slotChooseSheetFile()
{
	const BString& fileName = BFileDialog::OpenFile(this, "Open Image file", "./data");
	if (fileName.size())
	{
		_sheetFileNameEdit->setText(fileName);
		_styleSheetEdit->setName(fileName);
		_styleSheetEdit->load(fileName);
		BApplication::setStyleSheet(_styleSheetEdit->text());
		_saveSheetButton->setEnabled(false);
	}
}
void MainWindow::slotSaveSheetButtonClicked()
{
	const BString& fileName = _styleSheetEdit->name();
	_styleSheetEdit->save(fileName);
	_saveSheetButton->setEnabled(false);
}
void MainWindow::slotStyleSheetEditFinished(BObject* object, const BValue& value)
{
	BTextEdit* textEdit = dynamic_cast<BTextEdit*>(object);
	if (textEdit)
	{
		const BString& sheet = textEdit->text();
		BApplication::resetStyles();
		BApplication::setStyleSheet(sheet);
	}
}
void MainWindow::slotMainChildrenFramed(BWidget* widget, const BValue& value)
{
	if (BListWidget* listWidget = dynamic_cast<BListWidget*>(this->find("list")))
	{
		if (BListItem* item = listWidget->itemOfAsset(widget))
		{
			if (item->selected())
			{
				BPainter painter(widget);
				painter.setColor(200, 0, 0);
				int w = widget->width();
				int h = widget->height();
				painter.drawRect(1, 0, w - 1, h - 1);
			}
		}
	}
}

void MainWindow::slotShortcutTriggered(BObject* object, const BValue& value)
{
	const BString& sheet = _sheetFileNameEdit->text();
	BApplication::resetStyles();
	BApplication::setStyleSheet(sheet);
}

void MainWindow::showEvent(const BEvent& event)
{
	BMainWindow::showEvent(event);
	if (BListWidget* listWidget = dynamic_cast<BListWidget*>(this->find("list")))
	{
		for (int i = 0; i < this->childCount(); i++)
		{
			BWidget* widget = this->child(i);
			BListItem* item = listWidget->addItem(widget->name() + " : " + widget->className());
			item->setAsset(widget);
			connect(widget, Signal_Framed, &MainWindow::slotMainChildrenFramed);
		}
	}
}

